package com.mi.rule.generator._0_0_0_yuan_zhuang;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 数据库 持久化 生成器
 *
 * @author 王永吉
 * @date 2019/6/21 17:26
 */
public class CodeGenerator {
    private static String mapperPath = "/generator/resources/dao/_generator";//资源生成位置//mapper-xml文件位置
    private static String codePath = "/generator/";// 生成的模板文件所在位置
    private final static String parentPackage = "com.estate.mybatis._generator";// 代码包结构(根据项目自己修改)
    private final static String daoPackageName = "dao";//dao包名（随便改）
    private final static String entityPackageName = "entity";// entity包名（随便改）
    //TODO 数据源
    private final static String ip = "47.95.230.189";
    private final static String port = "3309";
    private final static String databaseName = "decoration";
    private final static String driverName = "com.mysql.cj.jdbc.Driver";
    private final static String username = "root";
    private final static String password = "1234qwer";
    //    private final static String password = "123456";
    private final static String url = "jdbc:mysql://"
            + ip + ":" + port + "/" + databaseName + "?"
            + "serverTimezone=Asia/Shanghai&characterEncoding=UTF8&"
            + "zeroDateTimeBehavior=convertToNull&useUnicode=true&"
            + "useSSL=false&useTimezone=false";

    public static void main(String[] args) {
        create();
    }

    //启动
    public static void create() {
        AutoGenerator mpg = new AutoGenerator();
        GlobalConfig gc = new GlobalConfig();
        ceLueAll(gc);

        //
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + codePath);
        gc.setAuthor("jobob");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);
        setSimple(mpg, projectPath);

        //
        StrategyConfig strategy = new StrategyConfig();
        ceLue(strategy);
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

    //配置全局策略
    private static void ceLueAll(GlobalConfig gc) {
        gc.setActiveRecord(true);//开启 Module 模式
        gc.setMapperName("%sDao");//修改 命名
    }

    //配置数据库策略
    private static void ceLue(StrategyConfig strategy) {
        strategy.setEntityLombokModel(true);//Lombok开启
        strategy.setNaming(NamingStrategy.underline_to_camel);//表命名策略->（驼峰）
        strategy.setColumnNaming(NamingStrategy.no_change);//字段命名策略->(不改变)
        strategy.setTablePrefix(getPrefixList());//去表前缀
//        strategy.setFieldPrefix(getFieldPrefixList());//去字段前缀
//        strategy.setInclude(getInclude()); //生成指定表
//        strategy.setExclude(getExclude());//不生成指定表
        strategy.setEntityBuilderModel(true);//构造者模式实体
        strategy.setEntityColumnConstant(true); //生成字段常量
        strategy.setEntityTableFieldAnnotationEnable(true);//生成字段注解
        strategy.setRestControllerStyle(false);//RestController注解->不生成
        // strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
        //strategy.setSuperControllerClass("com.sample.model.common.BaseController"); //指定 顶层 Controller
        //strategy.setSuperEntityClass("com.sample.model.common.BaseEntity"); //指定 顶层 实体类
        //strategy.setSuperEntityColumns("id");   //抽出公用 字段
        //strategy.setControllerMappingHyphenStyle(true);    //驼峰 变为  "-"
    }

    private static void setSimple(AutoGenerator mpg, String projectPath) {
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl(url);
        dsc.setDriverName(driverName);
        dsc.setUsername(username);
        dsc.setPassword(password);
        mpg.setDataSource(dsc);

        //        包
        PackageConfig pc = new PackageConfig();
        pc.setParent(parentPackage);//设置包名
        pc.setMapper(daoPackageName);//改包名
        pc.setEntity(entityPackageName);//改包名
        mpg.setPackageInfo(pc);

        //        模板
        mpg.setTemplate(new TemplateConfig().setEntity("/templates/entity.java"));

        //
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + mapperPath + "/" + tableInfo.getEntityName() + "Dao" + StringPool.DOT_XML;
            }
        });
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
            }
        };
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
    }

    private static JSONObject yamlToJson(String s) {
        Map<String, Object> loaded = null;
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(loaded);
        JSONObject spring = (JSONObject) jsonObject.get("spring");
        JSONObject datasource = (JSONObject) spring.get("datasource");
        return datasource;
    }

    //去除表前缀
    private static String[] getPrefixList() {
        ArrayList<String> arrayList = new ArrayList<>();

        for (int i = 0; i < 26; i++) {
            String s = (char) ('a' + i) + "_";
            arrayList.add(s);
        }
        arrayList.add("0_");
        arrayList.add("_");
        System.err.println("去除 表前缀----------------------------------------->开始");
        arrayList.forEach(x -> {
            System.err.println("去除  " + x);
        });
        System.err.println("去除 表前缀----------------------------------------->结束\n\n");

        return getArray(arrayList);
    }

    //去除字段前缀
    private static String[] getFieldPrefixList() {
        ArrayList<String> arrayList = new ArrayList<>();

        for (int i = 0; i < 26; i++) {
            String s = (char) ('a' + i) + "_";
            arrayList.add(s);
        }
        arrayList.add("0_");
        arrayList.add("_");
        System.err.println("去除 字段前缀----------------------------------------->开始");
        arrayList.forEach(x -> {
            System.err.println("去除  " + x);
        });
        System.err.println("去除 字段前缀----------------------------------------->结束\n\n");
        return getArray(arrayList);
    }

    //返回不生成的表
    private static String[] getExclude() {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("_a_permission_menu");
        arrayList.add("_link_role_menu");
        arrayList.add("_link_role_resource");
        arrayList.add("_log_exception");
        arrayList.add("_log_operate");
        arrayList.add("_permission_resource");
        arrayList.add("_permission_user");
        System.err.println("指定不生成的表----------------------------------------->开始");
        arrayList.forEach(x -> {
            System.err.println("不生成  " + x);
        });
        System.err.println("指定不生成的表----------------------------------------->结束\n\n");
        return getArray(arrayList);
    }

    //返回生成拿些表
    private static String[] getInclude() {
        ArrayList<String> arrayList = new ArrayList<>();
        System.err.println("指定生成的表----------------------------------------->开始");
        arrayList.forEach(x -> {
            System.err.println("指定生成  " + x);
        });
        System.err.println("指定生成的表----------------------------------------->结束\n\n");
        return getArray(arrayList);
    }

    static <T> T[] getArray(ArrayList<T> arrayList) {
        if (arrayList.size() > 0) {
            if (arrayList.get(0) instanceof String) {
                String[] strings = new String[arrayList.size()];
                for (int i = 0; i < arrayList.size(); i++) {
                    strings[i] = arrayList.get(i).toString();
                }
                return ((T[]) strings);
            }
            if (arrayList.get(0) instanceof Integer) {
                Integer[] ints = new Integer[arrayList.size()];
                for (int i = 0; i < arrayList.size(); i++) {
                    ints[i] = (Integer) arrayList.get(i);
                }
                return ((T[]) ints);
            }
        }
        return ((T[]) new String[]{});
    }

}



